<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\InvalidRequestException;
use App\Models\Book;
use App\Models\BookComment;
use App\Models\Order;
use App\Models\OrderExpressInfo;
use App\Models\OrderItem;
use App\Models\User;
use App\Models\UserAddress;
use App\Models\UserLikeCategory;
use Carbon\Carbon;
use Illuminate\Http\Request;
use DB;
use App\Common\ErrorCode;
use Mockery\Exception;
use EasyWeChat;

class OrdersController extends BaseController
{
    public function check(Request $request)
    {
        if(empty($this->user_id))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $user = User::query()->find($this->user_id);

        //dd($user);
        $is_open_card = 0;
        $status = 0;  //允许下单
        if($user->is_vip == 0)
        {
            $status = 1;  //不是会员
        }
        elseif($user->is_vip == -1)
        {
            $status = 2;  //会员过期
        }
        else
        {
            if(!empty($user->vip_end_time) && !empty($user->vip_start_time))
            {
                $timediff = $user->vip_end_time - $this->time;
                $day = ceil($timediff/86400);

                if($day <= 7)
                {
                    $status = 4;  //会员天数小于7天
                }
                else
                {
                    //判断是否有租用未还的订单
                    $order_info = Order::query()->where('user_id',$this->user_id)->whereIn('status',[0,1,2])->exists();
                    if(!empty($order_info))
                    {
                        $status = 3;  //有租用中的订单
                    }
                }

                $is_open_card = 1;
            }
            else
            {
                //判断是否有租用未还的订单
                $order_info = Order::query()->where('user_id',$this->user_id)->whereIn('status',[0,1,2])->exists();
                if(!empty($order_info))
                {
                    $status = 3;  //有租用中的订单
                }
            }
        }

        //检测是否开卡

        return $this->success([
            'status' => $status,
            'is_open_card' => $is_open_card
        ]);
    }

    public function store(Request $request)
    {
        $address_id = intval($request->input('address_id'));
        $items = $request->input('items');

        if(empty($this->user_id) || empty($address_id) || empty($items))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $user = User::query()->find($this->user_id);
        if(empty($user->telephone))
        {
            return $this->error(10000,'请先绑定手机号');
        }

        if($user->is_vip != 1)
        {
            return $this->error(10000,'请先成为会员');
        }
        //判断是否有租用中的订单
        /*$order_info = Order::query()->where('user_id',$this->user_id)->where(function ($query){
            $query->whereIn('status',[0,1,2])->orWhere(function ($query){
                $query->where('status',3)->whereIn('back_status',[0,1]);
            });
        })->exists();*/
        $order_info = Order::query()->where('user_id',$this->user_id)->whereIn('status',[0,1,2])->exists();
        if(!empty($order_info))
        {
            return $this->error(10000,'存在租用中的订单');
        }

        //会员天数小于等于7天无法下单
        $day = 0;
        if(!empty($user->vip_end_time) && !empty($user->vip_start_time))
        {
            if($user->vip_end_time >= $this->time)
            {
                $timediff = $user->vip_end_time - $this->time;
                $day = ceil($timediff/86400);
            }
        }
        else
        {
            $day = DB::table('user_vip_orders')->where('user_id',$this->user_id)->where('is_used',0)->where('status',1)->sum('vip_days');
        }
        if($day <= 7)
        {
            return $this->error(10000,'会员天数少于等于7天无法下单');
        }

        $order = DB::transaction(function () use ($request, $user) {
            $address_id = $request->input('address_id');
            $address = UserAddress::query()->find($address_id);

            // 更新此地址的最后使用时间
            $address->update([
                'last_used_at' => time()
            ]);

            // 创建一个订单
            $order   = new Order([
                'address_id' => $address_id,
                'receive_address' => $address->address,
                'receive_province' => $address->province,
                'receive_city' => $address->city,
                'receive_area' => $address->area,
                'receive_contact_name' => $address->contact_name,
                'receive_contact_telephone' => $address->contact_telephone,
            ]);

            // 订单关联到当前用户
            $order->user()->associate($user);

            // 写入数据库
            $order->save();

            $items = $request->input('items');
            $items_arr = json_decode($items,true);

            $book_ids = [];

            foreach ($items_arr as $v)
            {
                $book_ids[] = $v['book_id'];

                $book = Book::query()->find($v['book_id']);

                if($book->decreaseStore() <= 0)
                {
                    throw new InvalidRequestException('库存不足');
                }

                $item = $order->items()->make([
                    'user_id' => $user->id
                ]);
                $item->book()->associate($book);
                $item->save();

                //加喜欢的分类权重
                UserLikeCategory::addUserLikeCategoryScore($this->user_id,$book->category_id,UserLikeCategory::ORDER_WEIGHT);
            }

            // 将下单的商品从购物车中移除
            $user->carts()->whereIn('book_id',$book_ids)->delete();

            //下单提交成功短信提醒
            $sms = app('easysms');
            try {
                $sms->send($user->telephone,[
                    'template' => 'SMS_142383195',
                    'data' => [
                        'name' => $user->wechat_nickname
                    ],
                ]);
            } catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
                $message = $exception->getException('aliyun')->getMessage();
                dd($message);
            }

            try {
                $sms->send('15101016067',[
                    'template' => 'SMS_146808084',
                    'data' => [

                    ],
                ]);
            } catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
                $message = $exception->getException('aliyun')->getMessage();
                dd($message);
            }

            try {
                $sms->send('15811112206',[
                    'template' => 'SMS_146808084',
                    'data' => [

                    ],
                ]);
            } catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
                $message = $exception->getException('aliyun')->getMessage();
                dd($message);
            }

            return $order;
        });

        return $this->success();
    }

    public function index(Request $request)
    {
        $page = intval($request->input('page',1));
        $per_page = intval($request->input('per_page',20));
        $type = intval($request->input('type'));

        if(empty($this->user_id) || empty($type) || !in_array($type,[1,2,3]))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $builder  =Order::query()->where('user_id',$this->user_id);
        if($type == 1)
        {
            //待收货
            $builder->whereIn('status',[0,1]);
        }
        elseif($type == 2)
        {
            //待归还
            $builder->where('status',2);
        }
        elseif($type == 3)
        {
            $builder->where('status',3);
        }

        $total_count = $builder->count();

        $page = max(1,$page);
        $offset = ($page - 1)*$per_page;
        $page_count = ceil($total_count/$per_page);

        $list = $builder->with(['items.book'])->offset($offset)->limit($per_page)->orderBy('id','desc')->get();
        //dd($list);

        $items = [];
        if(!empty($list))
        {
            foreach ($list as $v)
            {
                //print_r($v);
                $books = [];
                foreach ($v->items as $vv)
                {
                    $books[] = [
                        'id' => $vv->book->id,
                        'title' => $vv->book->title,
                        'image' => config('app.qiniu_image_domain').DIRECTORY_SEPARATOR.$vv->book->image,
                        'author' => $vv->book->author,
                    ];
                }
                $items[] = [
                    'id' => $v->id,
                    'created_at' => $v->created_at->toDateTimeString(),
                    'no' => $v->no,
                    'status' => $v->status,
                    'status_str' => Order::$statusMap[$v->status],
                    'back_status' => $v->status == 3?Order::$backStatusMap[$v->back_status]:'',
                    'books' => $books
                ];
            }
        }
        return $this->res([
            'data' => [
                '_meta' => [
                    'total_count' => $total_count,
                    'page_count' => $page_count,
                    'current_page' => $page,
                    'per_page' => $per_page
                ],
                'items' => $items
            ]
        ]);
    }

    public function express_info(Order $order)
    {
        $info = OrderExpressInfo::query()->where('order_id',$order->id)->where('type',1)->where('express_no',$order->express_no)->first();
        //print_r($info);

        $express_info = [];
        if(!empty($info->traces))
        {
            $traces = json_decode($info->traces,true);
            //print_r($traces);
            if(!empty($traces))
            {
                $express_info = array_reverse($traces);
            }
        }

        return $this->res([
            'data' => [
                'express_info' => $express_info,
                'address' => [
                    'receive_contact_telephone' => $order->receive_contact_telephone,
                    'receive_contact_name' => $order->receive_contact_name,
                    'receive_address' => $order->receive_address,
                    'receive_province' => $order->receive_province,
                    'receive_city' => $order->receive_city,
                    'receive_area' => $order->receive_area,
                    'express_name' => $order->express_name,
                    'express_no' => $order->express_no,
                ]
            ]
        ]);
    }

    public function histroy(Request $request)
    {
        $user_id = intval($request->input('user_id'));

        if(empty($user_id))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $order_ids = Order::query()->where('user_id',$user_id)->where('status','>',1)->pluck('id');
        //print_r($order_ids);
        $order_items = OrderItem::query()->with(['book'])->whereIn('order_id',$order_ids)->get();

        $items = [];
        if(!empty($order_items))
        {
            foreach ($order_items as $v)
            {
                $items[] = [
                    'id' => $v['id'],
                    'is_comment' => $v->is_comment,
                    'book_id' => $v['book_id'],
                    'book_title'=> $v->book->title,
                    'book_author'=> $v->book->author,
                    'book_image' => config('app.qiniu_image_domain').DIRECTORY_SEPARATOR.$v->book->image,
                ];
            }
        }
        return $this->res([
            'data' => $items
        ]);
    }

    public function comment(Request $request)
    {
        $user_id = intval($request->input('user_id'));
        $id = intval($request->input('id'));
        $rate = intval($request->input('rate'));
        $content = $request->input('content');

        if(empty($user_id) || empty($id) || empty($rate) || empty($content) || !in_array($rate,[1,2,3,4,5]))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $order_item = OrderItem::query()->where('id',$id)->first();
        if($order_item->is_comment)
        {
            return $this->error(10000,'已评价');
        }

        DB::beginTransaction();

        try{
            BookComment::query()->create([
                'user_id' => $user_id,
                'book_id' => $order_item->book_id,
                'rate' => $rate,
                'content' => $content,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
                'type' => 1,
                'status' => 1
            ]);

            $order_item->update([
                'is_comment' => 1
            ]);

            /*$result = BookComment::query()
                ->where('book_id', $order_item->book_id)
                ->first([
                    DB::raw('count(*) as review_count'),
                    DB::raw('avg(rate) as rating')
                ]);
            // 更新商品的评分和评价数
            Book::query()->where('id',$order_item->book_id)->update([
                'review_count' => $result->review_count,
                'rating' => $result->rating,
            ]);*/
            Book::query()->where('id',$order_item->book_id)->increment('uncheck_comment_num');

            DB::commit();

            return $this->success([],'评价成功');
        } catch (\Exception $e){
            DB::rollback();//事务回滚
            //echo $e->getMessage();
            //echo $e->getCode();
            return $this->error(10000,$e->getMessage());
        }
    }

    public function back_order(Request $request)
    {
        $user_id = intval($request->input('user_id'));
        $order_id = intval($request->input('order_id'));
        $back_address_id = intval($request->input('address_id'));
        $back_order_time = $request->input('back_order_time');  //预约取件时间 2018-08-20 15:00:00

        if(empty($user_id) || empty($order_id) || empty($back_address_id) || empty($back_order_time))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $address = UserAddress::query()->where('id',$back_address_id)->first();
        if(empty($address))
        {
            return $this->error(10000,'地址不存在');
        }

        $order = Order::query()->where('user_id',$user_id)->where('id',$order_id)->first();
        if(empty($order))
        {
            return $this->error(10000,'订单不存在');
        }

        if($order->status != 2)
        {
            return $this->error(10000,'订单状态错误');
        }

        $user = User::query()->where('id',$user_id)->first();

        //构造在线下单提交信息
        $eorder = [];
        $eorder["ShipperCode"] = "SF";
        $eorder["OrderCode"] = Order::findBackOrderNo();
        $eorder["PayType"] = 2;  //1-现付，2-到付，3-月结，4-第三
        $eorder["ExpType"] = 2;
        $eorder["StartDate"] = $back_order_time;

        $sender = [];
        $sender["Name"] = $address->contact_name;
        $sender["Mobile"] = $address->contact_telephone;
        $sender["ProvinceName"] = $address->province;
        $sender["CityName"] = $address->city;
        $sender["ExpAreaName"] = $address->area;
        $sender["Address"] = $address->address;

        $receiver = [];
        $receiver["Name"] = "鲸鱼借书";
        $receiver["Mobile"] = "15888825922";
        $receiver["ProvinceName"] = "浙江省";
        $receiver["CityName"] = "杭州市";
        $receiver["ExpAreaName"] = "余杭区";
        $receiver["Address"] = "万科未来城二期21-1-2302";

        /*$receiver["Name"] = "小严";
        $receiver["Mobile"] = "18260165847";
        $receiver["ProvinceName"] = "江苏省";
        $receiver["CityName"] = "苏州市";
        $receiver["ExpAreaName"] = "吴江区";
        $receiver["Address"] = "太湖新城开平路新城吾悦花园2期7幢";*/

        $commodityOne = [];
        $commodityOne["GoodsName"] = "鲸鱼有书(还书)";
        $commodity = [];
        $commodity[] = $commodityOne;

        $eorder["Sender"] = $sender;
        $eorder["Receiver"] = $receiver;
        $eorder["Commodity"] = $commodity;

        //调用在线下单
        $jsonParam = json_encode($eorder, JSON_UNESCAPED_UNICODE);
        $jsonResult = $this->_submitOOrder($jsonParam);

        //解析在线下单返回结果
        $result = json_decode($jsonResult, true);
        //print_r($result);die;
        if($result['Success'] && $result['ResultCode'] == 100)
        {
            //下单成功
            Order::query()->where('id',$order_id)->update([
                'back_express_code' => $result['Order']['ShipperCode'],
                'back_uniquer_request_number' => $result['UniquerRequestNumber'],
                'back_order_no' => $result['Order']['OrderCode'],
                'back_created_at' => time(),
                'back_order_time' => strtotime($back_order_time),
                'back_contact_telephone' => $address->contact_telephone,
                'back_contact_name' => $address->contact_name,
                'back_address_province' => $address->province,
                'back_address_city' => $address->city,
                'back_address_area' => $address->area,
                'back_address' => $address->address,
                'back_address_id' => $back_address_id,
                'status' => 3,
                'back_status' => 1,
                'back_express_no' => $result['Order']['LogisticCode'],
                'back_express_name' => '顺丰速运'
            ]);

            //短信提醒

            $back_day = date('Y-m-d',strtotime($back_order_time));
            $day1 = date('Y-m-d',strtotime("+1 day"));
            $day2 = date('Y-m-d',strtotime("+2 days"));

            $show_day = $back_day;
            if($day1 == $back_day)
            {
                $show_day = '明天';
            }
            if($day2 == $back_day)
            {
                $show_day = '后天';
            }


            if(!empty($user->telephone) && !empty($user->wechat_nickname))
            {
                $sms = app('easysms');
                try {
                    $sms->send($user->telephone,[
                        'template' => 'SMS_157683376',
                        'data' => [
                            'name' => $user->wechat_nickname,
                            'time' => $show_day.date('H:i',strtotime($back_order_time)),
                        ],
                    ]);
                } catch (\Overtrue\EasySms\Exceptions\NoGatewayAvailableException $exception) {
                    $message = $exception->getException('aliyun')->getMessage();
                    dd($message);
                }
            }
            
            return $this->success([
                'order_id' => $order_id
            ],'预约还书成功');
        }

        \Log::debug('kdniao_eorderservice',$result);
        return $this->error(10000,'预约还书失败');
    }

    public function back_order_send_template_message(Request $request)
    {
        $order_id = intval($request->input('order_id'));
        $page = $request->input('page');
        $form_id = $request->input('form_id');

        if(empty($form_id) || empty($order_id))
        {
            return $this->error(ErrorCode::PARAMS_NOT_VALID_CODE,ErrorCode::PARAMS_NOT_VALID_MESSAGE);
        }

        $order = Order::query()->with(['items.book'])->where('id',$order_id)->first();

        $book_title = [];
        if(!empty($order->items))
        {
            foreach ($order->items as $item)
            {
                $book_title[] = '《'.$item->book->title.'》';
            }
        }

        if(empty($order))
        {
            return $this->error(10000,'订单不存在');
        }

        if($order->status != 3 || $order->back_status != 1)
        {
            return $this->error(10000,'订单状态');
        }

        $user = User::query()->where('id',$order->user_id)->first();

        //$touser = $user->wechat_openid;
        $touser = 'oyYnM4jX5NF3lpbkIprqGd7PQK0Q';
        //发送模板消息
        $miniProgram = EasyWeChat::miniProgram(); // 小程序
        $ret = $miniProgram->template_message->send([
            'touser' => $touser,
            'template_id' => 'a0y4ssss6CFG_OsCvai0qGVLESoZ6p1dnZ3DjGKNAIM',
            'page' => $page,
            'form_id' => $form_id,
            'data' => [
                'keyword1' => '预约还书',
                'keyword2' => '申请将'.implode(' ',$book_title).'寄回',
                'keyword3' => '等待快递上门取件',
                'keyword4' => '您预约快递上门取件时间为<'.date('Y年m月d日 H:i',$order->back_order_time).'>',
                'keyword5' => $order->back_contact_name.' '.$order->back_contact_telephone,
                'keyword6' => '请提前将要归还的书放入书袋中，顺丰小哥会在您指定的时间上门取件，保持手机畅通。'
            ],
        ]);

        var_dump($ret);die;
        return $this->success([]);
    }

    private function _submitOOrder($requestData)
    {
        //$url = 'http://testapi.kdniao.cc:8081/api/oorderservice';
        $url = 'http://api.kdniao.com/api/eorderservice';
        $ebusinessid = '1363157';
        $appkey = 'f426aae4-89fa-4a90-863c-08c96328b7f6';
        $datas = array(
            'EBusinessID' => $ebusinessid,
            'RequestType' => '1001',
            'RequestData' => urlencode($requestData) ,
            'DataType' => '2',
        );
        $datas['DataSign'] = kdniao_encrypt($requestData, $appkey);

        $result = sendPost($url, $datas);

        //根据公司业务处理返回的信息......

        return $result;
    }

    public function cancel_back_order()
    {
        $requestData = [
            'ShipperCode' => 'ZTO',
            'OrderCode' => '20180819213623975192',
            'ExpNo' => '544805323636'
        ];
        $requestData = json_encode($requestData, JSON_UNESCAPED_UNICODE);

        $url = 'http://api.kdniao.cc/api/EOrderService';
        $ebusinessid = '1363157';
        $appkey = 'f426aae4-89fa-4a90-863c-08c96328b7f6';
        $datas = array(
            'EBusinessID' => $ebusinessid,
            'RequestType' => '1147',
            'RequestData' => urlencode($requestData) ,
            'DataType' => '2',
        );
        $datas['DataSign'] = kdniao_encrypt($requestData, $appkey);

        $result = sendPost($url, $datas);
        print_r($result);
        //根据公司业务处理返回的信息......

        return $result;
    }

    public function back_order_detail(Order $order)
    {
        $detail = Order::query()->with(['items.book'])->where('id',$order->id)->first();
        //print_r($detail);

        $data = [
            'id' => $order->id,
            'status' => $detail->status,
            'back_status' => $detail->back_status,
            'back_created_at' => date('Y-m-d H:i:s',$detail->back_created_at),
            'back_order_time' => date('Y-m-d H:i:s',$detail->back_order_time),
            'back_address' => $detail->back_address,
            'back_address_province' => $detail->back_address_province,
            'back_address_city' => $detail->back_address_city,
            'back_address_area' => $detail->back_address_area,
            'back_contact_name' => $detail->back_contact_name,
            'back_contact_telephone' => $detail->back_contact_telephone,
            'back_express_no' => $detail->back_express_no,
        ];

        $books = [];
        if(!empty($detail->items))
        {
            foreach ($detail->items as $v)
            {
                $books[] = [
                    'book_id' => $v->book_id,
                    'book_title' => $v->book->title,
                    'book_image' => config('app.qiniu_image_domain').DIRECTORY_SEPARATOR.$v->book->image,
                ];
            }
        }

        $data['books'] = $books;
        return $this->res([
            'data' => $data
        ]);
    }

    public function test(Request $request)
    {
        $order_id = $request->input('order_id');
        Order::query()->where('id',$order_id)->update([
            'status' => 2,
            'receive_time' => time(),
            'real_receive_time' => time()
        ]);
        return $this->success();
    }
}
